home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Codigo / hh / rsource.exe / Hexen Source / R_DATA.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-22  |  14.2 KB  |  677 lines

  1.  
  2. //**************************************************************************
  3. //**
  4. //** r_data.c : Heretic 2 : Raven Software, Corp.
  5. //**
  6. //** $RCSfile: r_data.c,v $
  7. //** $Revision: 1.8 $
  8. //** $Date: 96/03/12 12:04:04 $
  9. //** $Author: bgokey $
  10. //**
  11. //**************************************************************************
  12.  
  13. #include "h2def.h"
  14. #include "r_local.h"
  15. #include "p_local.h"
  16.  
  17. typedef struct
  18. {
  19.     int        originx;    // block origin (allways UL), which has allready
  20.     int        originy;    // accounted  for the patch's internal origin
  21.     int        patch;
  22. } texpatch_t;
  23.  
  24. // a maptexturedef_t describes a rectangular texture, which is composed of one
  25. // or more mappatch_t structures that arrange graphic patches
  26. typedef struct
  27. {
  28.     char        name[8];        // for switch changing, etc
  29.     short        width;
  30.     short        height;
  31.     short        patchcount;
  32.     texpatch_t    patches[1];        // [patchcount] drawn back to front
  33.                                 //  into the cached texture
  34. } texture_t;
  35.  
  36.  
  37.  
  38. int        firstflat, lastflat, numflats;
  39. int        firstpatch, lastpatch, numpatches;
  40. int        firstspritelump, lastspritelump, numspritelumps;
  41.  
  42. int            numtextures;
  43. texture_t    **textures;
  44. int            *texturewidthmask;
  45. fixed_t        *textureheight;        // needed for texture pegging
  46. int            *texturecompositesize;
  47. short        **texturecolumnlump;
  48. unsigned short        **texturecolumnofs;
  49. byte        **texturecomposite;
  50.  
  51. int            *flattranslation;        // for global animation
  52. int            *texturetranslation;    // for global animation
  53.  
  54. fixed_t        *spritewidth;        // needed for pre rendering
  55. fixed_t        *spriteoffset;
  56. fixed_t        *spritetopoffset;
  57.  
  58. lighttable_t    *colormaps;
  59.  
  60.  
  61. /*
  62. ==============================================================================
  63.  
  64.                         MAPTEXTURE_T CACHING
  65.  
  66. when a texture is first needed, it counts the number of composite columns
  67. required in the texture and allocates space for a column directory and any
  68. new columns.  The directory will simply point inside other patches if there
  69. is only one patch in a given column, but any columns with multiple patches
  70. will have new column_ts generated.
  71.  
  72. ==============================================================================
  73. */
  74.  
  75. /*
  76. ===================
  77. =
  78. = R_DrawColumnInCache
  79. =
  80. = Clip and draw a column from a patch into a cached post
  81. =
  82. ===================
  83. */
  84.  
  85. void R_DrawColumnInCache (column_t *patch, byte *cache, int originy, int cacheheight)
  86. {
  87.     int        count, position;
  88.     byte    *source, *dest;
  89.     
  90.     dest = (byte *)cache + 3;
  91.     
  92.     while (patch->topdelta != 0xff)
  93.     {
  94.         source = (byte *)patch + 3;
  95.         count = patch->length;
  96.         position = originy + patch->topdelta;
  97.         if (position < 0)
  98.         {
  99.             count += position;
  100.             position = 0;
  101.         }
  102.         if (position + count > cacheheight)
  103.             count = cacheheight - position;
  104.         if (count > 0)
  105.             memcpy (cache + position, source, count);
  106.         
  107.         patch = (column_t *)(  (byte *)patch + patch->length
  108. + 4);
  109.     }
  110. }
  111.  
  112.  
  113. /*
  114. ===================
  115. =
  116. = R_GenerateComposite
  117. =
  118. ===================
  119. */
  120.  
  121. void R_GenerateComposite (int texnum)
  122. {
  123.     byte        *block;
  124.     texture_t    *texture;
  125.     texpatch_t    *patch;    
  126.     patch_t        *realpatch;
  127.     int            x, x1, x2;
  128.     int            i;
  129.     column_t    *patchcol;
  130.     short        *collump;
  131.     unsigned short *colofs;
  132.     
  133.     texture = textures[texnum];
  134.     block = Z_Malloc (texturecompositesize[texnum], PU_STATIC, 
  135.         &texturecomposite[texnum]);    
  136.     collump = texturecolumnlump[texnum];
  137.     colofs = texturecolumnofs[texnum];
  138.         
  139. //
  140. // composite the columns together
  141. //
  142.     patch = texture->patches;
  143.         
  144.     for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
  145.     {
  146.         realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
  147.         x1 = patch->originx;
  148.         x2 = x1 + SHORT(realpatch->width);
  149.  
  150.         if (x1<0)
  151.             x = 0;
  152.         else
  153.             x = x1;
  154.         if (x2 > texture->width)
  155.             x2 = texture->width;
  156.  
  157.         for ( ; x<x2 ; x++)
  158.         {
  159.             if (collump[x] >= 0)
  160.                 continue;        // column does not have multiple patches
  161.             patchcol = (column_t *)((byte *)realpatch + 
  162.                 LONG(realpatch->columnofs[x-x1]));
  163.             R_DrawColumnInCache (patchcol, block + colofs[x], patch->originy,
  164.             texture->height);
  165.         }
  166.                         
  167.     }
  168.  
  169. // now that the texture has been built, it is purgable
  170.     Z_ChangeTag (block, PU_CACHE);
  171. }
  172.  
  173.  
  174. /*
  175. ===================
  176. =
  177. = R_GenerateLookup
  178. =
  179. ===================
  180. */
  181.  
  182. void R_GenerateLookup (int texnum)
  183. {
  184.     texture_t    *texture;
  185.     byte        *patchcount;        // [texture->width]
  186.     texpatch_t    *patch;    
  187.     patch_t        *realpatch;
  188.     int            x, x1, x2;
  189.     int            i;
  190.     short        *collump;
  191.     unsigned short    *colofs;
  192.     
  193.     texture = textures[texnum];
  194.  
  195.     texturecomposite[texnum] = 0;    // composited not created yet
  196.     texturecompositesize[texnum] = 0;
  197.     collump = texturecolumnlump[texnum];
  198.     colofs = texturecolumnofs[texnum];
  199.     
  200. //
  201. // count the number of columns that are covered by more than one patch
  202. // fill in the lump / offset, so columns with only a single patch are
  203. // all done
  204. //
  205.     patchcount = (byte *)alloca (texture->width);
  206.     memset (patchcount, 0, texture->width);
  207.     patch = texture->patches;
  208.         
  209.     for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
  210.     {
  211.         realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
  212.         x1 = patch->originx;
  213.         x2 = x1 + SHORT(realpatch->width);
  214.         if (x1 < 0)
  215.             x = 0;
  216.         else
  217.             x = x1;
  218.         if (x2 > texture->width)
  219.             x2 = texture->width;
  220.         for ( ; x<x2 ; x++)
  221.         {
  222.             patchcount[x]++;
  223.             collump[x] = patch->patch;
  224.             colofs[x] = LONG(realpatch->columnofs[x-x1])+3;
  225.         }
  226.     }
  227.     
  228.     for (x=0 ; x<texture->width ; x++)
  229.     {
  230.         if (!patchcount[x])
  231.         {
  232.             ST_Message ("R_GenerateLookup: column without a patch (%s)\n", texture->name);
  233.             return;
  234.         }
  235. //            I_Error ("R_GenerateLookup: column without a patch");
  236.         if (patchcount[x] > 1)
  237.         {
  238.             collump[x] = -1;    // use the cached block
  239.             colofs[x] = texturecompositesize[texnum];
  240.             if (texturecompositesize[texnum] > 0x10000-texture->height)
  241.                 I_Error ("R_GenerateLookup: texture %i is >64k",texnum);
  242.             texturecompositesize[texnum] += texture->height;
  243.         }
  244.     }    
  245. }
  246.  
  247.  
  248. /*
  249. ================
  250. =
  251. = R_GetColumn
  252. =
  253. ================
  254. */
  255.  
  256. byte *R_GetColumn (int tex, int col)
  257. {
  258.     int    lump, ofs;
  259.     
  260.     col &= texturewidthmask[tex];
  261.     lump = texturecolumnlump[tex][col];
  262.     ofs = texturecolumnofs[tex][col];
  263.     if (lump > 0)
  264.         return (byte *)W_CacheLumpNum(lump,PU_CACHE)+ofs;
  265.     if (!texturecomposite[tex])
  266.         R_GenerateComposite (tex);
  267.     return texturecomposite[tex] + ofs;
  268. }
  269.  
  270.  
  271. /*
  272. ==================
  273. =
  274. = R_InitTextures
  275. =
  276. = Initializes the texture list with the textures from the world map
  277. =
  278. ==================
  279. */
  280.  
  281. void R_InitTextures (void)
  282. {
  283.     maptexture_t    *mtexture;
  284.     texture_t        *texture;
  285.     mappatch_t    *mpatch;
  286.     texpatch_t    *patch;
  287.     int            i,j;
  288.     int            *maptex, *maptex2, *maptex1;
  289.     char        name[9], *names, *name_p;
  290.     int            *patchlookup;
  291.     int            totalwidth;
  292.     int            nummappatches;
  293.     int            offset, maxoff, maxoff2;
  294.     int            numtextures1, numtextures2;
  295.     int            *directory;
  296.  
  297. //
  298. // load the patch names from pnames.lmp
  299. //
  300.     name[8] = 0;
  301.     names = W_CacheLumpName ("PNAMES", PU_STATIC);
  302.     nummappatches = LONG ( *((int *)names) );
  303.     name_p = names+4;
  304.     patchlookup = alloca (nummappatches*sizeof(*patchlookup));
  305.     for (i=0 ; i<nummappatches ; i++)
  306.     {
  307.         strncpy (name,name_p+i*8, 8);
  308.         patchlookup[i] = W_CheckNumForName (name);
  309.     }
  310.     Z_Free (names);
  311.  
  312. //
  313. // load the map texture definitions from textures.lmp
  314. //
  315.     maptex = maptex1 = W_CacheLumpName ("TEXTURE1", PU_STATIC);
  316.     numtextures1 = LONG(*maptex);
  317.     maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
  318.     directory = maptex+1;
  319.  
  320.     if (W_CheckNumForName ("TEXTURE2") != -1)
  321.     {
  322.         maptex2 = W_CacheLumpName ("TEXTURE2", PU_STATIC);
  323.         numtextures2 = LONG(*maptex2);
  324.         maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
  325.     }
  326.     else
  327.     {
  328.         maptex2 = NULL;
  329.         numtextures2 = 0;
  330.         maxoff2 = 0;
  331.     }
  332.     numtextures = numtextures1 + numtextures2;
  333.  
  334.     textures = Z_Malloc (numtextures*4, PU_STATIC, 0);
  335.     texturecolumnlump = Z_Malloc (numtextures*4, PU_STATIC, 0);
  336.     texturecolumnofs = Z_Malloc (numtextures*4, PU_STATIC, 0);
  337.     texturecomposite = Z_Malloc (numtextures*4, PU_STATIC, 0);
  338.     texturecompositesize = Z_Malloc (numtextures*4, PU_STATIC, 0);
  339.     texturewidthmask = Z_Malloc (numtextures*4, PU_STATIC, 0);
  340.     textureheight = Z_Malloc (numtextures*4, PU_STATIC, 0);
  341.  
  342.     totalwidth = 0;
  343.  
  344.     for (i=0 ; i<numtextures ; i++, directory++)
  345.     {
  346.         if (i == numtextures1)
  347.         {    // start looking in second texture file
  348.             maptex = maptex2;
  349.             maxoff = maxoff2;
  350.             directory = maptex+1;
  351.         }
  352.  
  353.         offset = LONG(*directory);
  354.         if (offset > maxoff)
  355.             I_Error ("R_InitTextures: bad texture directory");
  356.         mtexture = (maptexture_t *) ( (byte *)maptex + offset);
  357.         texture = textures[i] = Z_Malloc (sizeof(texture_t) 
  358.             + sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1), PU_STATIC,
  359.             0);
  360.         texture->width = SHORT(mtexture->width);
  361.         texture->height = SHORT(mtexture->height);
  362.         texture->patchcount = SHORT(mtexture->patchcount);
  363.         memcpy (texture->name, mtexture->name, sizeof(texture->name));
  364.         mpatch = &mtexture->patches[0];
  365.         patch = &texture->patches[0];
  366.         for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
  367.         {
  368.             patch->originx = SHORT(mpatch->originx);
  369.             patch->originy = SHORT(mpatch->originy);
  370.             patch->patch = patchlookup[SHORT(mpatch->patch)];
  371.             if (patch->patch == -1)
  372.                 I_Error (
  373.                 "R_InitTextures: Missing patch in texture %s",texture->name);
  374.         }        
  375.         texturecolumnlump[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
  376.         texturecolumnofs[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
  377.         j = 1;
  378.         while (j*2 <= texture->width)
  379.             j<<=1;
  380.         texturewidthmask[i] = j-1;
  381.         textureheight[i] = texture->height<<FRACBITS;
  382.         
  383.         totalwidth += texture->width;
  384.     }
  385.  
  386.     Z_Free (maptex1);
  387.     if (maptex2)
  388.         Z_Free (maptex2);
  389.  
  390. //
  391. // precalculate whatever possible
  392. //        
  393.     for (i=0 ; i<numtextures ; i++)
  394.     {
  395.         R_GenerateLookup (i);
  396.         if(!(i&31)) ST_Progress();
  397.     }
  398.  
  399. //
  400. // translation table for global animation
  401. //
  402.     texturetranslation = Z_Malloc ((numtextures+1)*4, PU_STATIC, 0);
  403.     for (i=0 ; i<numtextures ; i++)
  404.         texturetranslation[i] = i;
  405. }
  406.  
  407.  
  408. /*
  409. ================
  410. =
  411. = R_InitFlats
  412. =
  413. =================
  414. */
  415.  
  416. void R_InitFlats (void)
  417. {
  418.     int        i;
  419.     
  420.     firstflat = W_GetNumForName ("F_START") + 1;
  421.     lastflat = W_GetNumForName ("F_END") - 1;
  422.     numflats = lastflat - firstflat + 1;
  423.     
  424. // translation table for global animation
  425.     flattranslation = Z_Malloc ((numflats+1)*4, PU_STATIC, 0);
  426.     for (i=0 ; i<numflats ; i++)
  427.         flattranslation[i] = i;
  428. }
  429.  
  430.  
  431. /*
  432. ================
  433. =
  434. = R_InitSpriteLumps
  435. =
  436. = Finds the width and hoffset of all sprites in the wad, so the sprite doesn't
  437. = need to be cached just for the header during rendering
  438. =================
  439. */
  440.  
  441. void R_InitSpriteLumps (void)
  442. {
  443.     int        i;
  444.     patch_t    *patch;
  445.  
  446.     firstspritelump = W_GetNumForName ("S_START") + 1;
  447.     lastspritelump = W_GetNumForName ("S_END") - 1;
  448.     numspritelumps = lastspritelump - firstspritelump + 1;
  449.     spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  450.     spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  451.     spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  452.  
  453.     for (i=0 ; i< numspritelumps ; i++)
  454.     {
  455.         if (!(i&127)) ST_Progress();
  456.         patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
  457.         spritewidth[i] = SHORT(patch->width)<<FRACBITS;
  458.         spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
  459.         spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
  460.     }
  461. }
  462.  
  463.  
  464. /*
  465. ================
  466. =
  467. = R_InitColormaps
  468. =
  469. =================
  470. */
  471.  
  472. void R_InitColormaps (void)
  473. {
  474.     int    lump, length;
  475. //
  476. // load in the light tables
  477. // 256 byte align tables
  478. //
  479.     lump = W_GetNumForName("COLORMAP");
  480.     length = W_LumpLength (lump) + 255;
  481.     colormaps = Z_Malloc (length, PU_STATIC, 0);
  482.     colormaps = (byte *)( ((int)colormaps + 255)&~0xff);
  483.     W_ReadLump (lump,colormaps);
  484. }
  485.  
  486.  
  487. /*
  488. ================
  489. =
  490. = R_InitData
  491. =
  492. = Locates all the lumps that will be used by all views
  493. = Must be called after W_Init
  494. =================
  495. */
  496.  
  497. void R_InitData (void)
  498. {
  499.     R_InitTextures();
  500.     R_InitFlats();
  501.     R_InitSpriteLumps();
  502.     R_InitColormaps();
  503. }
  504.  
  505. //=============================================================================
  506.  
  507. /*
  508. ================
  509. =
  510. = R_FlatNumForName
  511. =
  512. ================
  513. */
  514.  
  515. int    R_FlatNumForName (char *name)
  516. {
  517.     int        i;
  518.     char    namet[9];
  519.  
  520.     i = W_CheckNumForName (name);
  521.     if (i == -1)
  522.     {
  523.         namet[8] = 0;
  524.         memcpy (namet, name,8);
  525.         I_Error ("R_FlatNumForName: %s not found",namet);
  526.     }
  527.     return i - firstflat;
  528. }
  529.  
  530.  
  531. /*
  532. ================
  533. =
  534. = R_CheckTextureNumForName
  535. =
  536. ================
  537. */
  538.  
  539. int    R_CheckTextureNumForName (char *name)
  540. {
  541.     int        i;
  542.     
  543.     if (name[0] == '-')        // no texture marker
  544.         return 0;
  545.         
  546.     for (i=0 ; i<numtextures ; i++)
  547.         if (!strncasecmp (textures[i]->name, name, 8) )
  548.             return i;
  549.         
  550.     return -1;
  551. }
  552.  
  553.  
  554. /*
  555. ================
  556. =
  557. = R_TextureNumForName
  558. =
  559. ================
  560. */
  561.  
  562. int    R_TextureNumForName (char *name)
  563. {
  564.     int        i;
  565.     //char    namet[9];
  566.     
  567.     i = R_CheckTextureNumForName (name);
  568.     if (i==-1)
  569.         I_Error ("R_TextureNumForName: %s not found",name);
  570.     
  571.     return i;
  572. }
  573.  
  574.  
  575. /*
  576. =================
  577. =
  578. = R_PrecacheLevel
  579. =
  580. = Preloads all relevent graphics for the level
  581. =================
  582. */
  583.  
  584. int        flatmemory, texturememory, spritememory;
  585.  
  586. void R_PrecacheLevel (void)
  587. {
  588.     char            *flatpresent;
  589.     char            *texturepresent;
  590.     char            *spritepresent;
  591.     int                i,j,k, lump;
  592.     texture_t        *texture;
  593.     thinker_t        *th;
  594.     spriteframe_t    *sf;
  595.  
  596.     if (demoplayback)
  597.         return;
  598.             
  599. //
  600. // precache flats
  601. //    
  602.     flatpresent = alloca(numflats);
  603.     memset (flatpresent,0,numflats);    
  604.     for (i=0 ; i<numsectors ; i++)
  605.     {
  606.         flatpresent[sectors[i].floorpic] = 1;
  607.         flatpresent[sectors[i].ceilingpic] = 1;
  608.     }
  609.     
  610.     flatmemory = 0;
  611.     for (i=0 ; i<numflats ; i++)
  612.         if (flatpresent[i])
  613.         {
  614.             lump = firstflat + i;
  615.             flatmemory += lumpinfo[lump].size;
  616.             W_CacheLumpNum(lump, PU_CACHE);
  617.         }
  618.         
  619. //
  620. // precache textures
  621. //
  622.     texturepresent = alloca(numtextures);
  623.     memset (texturepresent,0, numtextures);
  624.     
  625.     for (i=0 ; i<numsides ; i++)
  626.     {
  627.         texturepresent[sides[i].toptexture] = 1;
  628.         texturepresent[sides[i].midtexture] = 1;
  629.         texturepresent[sides[i].bottomtexture] = 1;
  630.     }
  631.     
  632.     texturepresent[Sky1Texture] = 1;
  633.     texturepresent[Sky2Texture] = 1;
  634.  
  635.     texturememory = 0;
  636.     for (i=0 ; i<numtextures ; i++)
  637.     {
  638.         if (!texturepresent[i])
  639.             continue;
  640.         texture = textures[i];
  641.         for (j=0 ; j<texture->patchcount ; j++)
  642.         {
  643.             lump = texture->patches[j].patch;
  644.             texturememory += lumpinfo[lump].size;
  645.             W_CacheLumpNum(lump , PU_CACHE);
  646.         }
  647.     }
  648.     
  649. //
  650. // precache sprites
  651. //
  652.     spritepresent = alloca(numsprites);
  653.     memset (spritepresent,0, numsprites);
  654.     
  655.     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  656.     {
  657.         if (th->function == P_MobjThinker)
  658.             spritepresent[((mobj_t *)th)->sprite] = 1;
  659.     }
  660.     
  661.     spritememory = 0;
  662.     for (i=0 ; i<numsprites ; i++)
  663.     {
  664.         if (!spritepresent[i])
  665.             continue;
  666.         for (j=0 ; j<sprites[i].numframes ; j++)
  667.         {
  668.             sf = &sprites[i].spriteframes[j];
  669.             for (k=0 ; k<8 ; k++)
  670.             {
  671.                 lump = firstspritelump + sf->lump[k];
  672.                 spritememory += lumpinfo[lump].size;
  673.                 W_CacheLumpNum(lump , PU_CACHE);
  674.             }
  675.         }
  676.     }
  677. }
  678.